import { GridContent } from '@ant-design/pro-layout';
import { forwardRef, useState, useEffect, useImperativeHandle } from 'react';
import { Input, Form, Select, Button, FormInstance } from 'antd';
import { serverSelectList } from '@/services/project';
import { LeftOutlined, EditOutlined } from '@ant-design/icons';
// import { parse } from 'qs';
import Step from '@/pages/project/step';
import './index.less';
import Files from '@/pages/project/files';
const { Option } = Select;
const { TextArea } = Input;

// eslint-disable-next-line @typescript-eslint/no-unused-vars
const ProcessSetting: any = forwardRef((props: { defaultValue: PRO.deployConfig }, ref) => {
  const [form] = Form.useForm();

  // eslint-disable-next-line @typescript-eslint/no-shadow
  const [serverList, setServerList] = useState([]);
  const [beforeHookList, setBeforeHookList] = useState<PRO.step[]>([]);
  const [afterHook, setAfterHook] = useState<PRO.step[]>([]);

  const [isSetBeforeHook, setIsSetBeforeHook] = useState(true);
  const [showModal, setShowModal] = useState(false);
  const [isPublish, setIsPublish] = useState(false);
  const [modelData, setModelData] = useState<PRO.step>();
  const [files, setFiles] = useState<PRO.files[]>([]);
  const [file, setFile] = useState<PRO.files>({
    content: '',
    path: '',
    template_args: '',
    unique_id: '',
    id: '',
  });
  const [showFiles, setShowFiles] = useState(false);
  const onSubmit = () => {
    return new Promise((resolve, reject) => {
      form
        .validateFields()
        .then(() => {
          // eslint-disable-next-line @typescript-eslint/no-unused-vars
          const data = form.getFieldsValue();
          data.before_hook = beforeHookList;
          data.after_hook = afterHook;
          data.files = files;
          resolve(data);
        })
        .catch((err) => {
          reject(err);
        });
    });
  };
  useImperativeHandle(ref, () => ({
    getFormData: onSubmit,
  }));
  const addHook = (data: PRO.step) => {
    let isAdd = true;

    let hookList = [];
    if (isSetBeforeHook) {
      hookList = beforeHookList;
    } else {
      hookList = afterHook;
    }
    hookList.map((value, index) => {
      if (value.unique_id == data.unique_id) {
        hookList[index] = data;
        isAdd = false;
      }
    });
    if (isAdd) {
      hookList.push(data);
    }
    if (isSetBeforeHook) {
      setBeforeHookList(hookList);
    } else {
      setAfterHook(hookList);
    }
  };
  const editHook = (data: {}) => {
    setShowModal(true);
    // @ts-ignore
    setModelData(data);
  };

  const editFiles = (data: PRO.files) => {
    setShowFiles(true);
    setFile(data);
  };

  const getServerList = async () => {
    const data = await serverSelectList();
    // @ts-ignore
    setServerList(data);
  };

  const addFiles = async (data: PRO.files) => {
    let isAdd = true;
    if (data.id == '') {
      // @ts-ignore
      delete data.id;
    }
    files.map((value, index) => {
      if (value.unique_id == data.unique_id) {
        files[index] = data;
        isAdd = false;
      }
    });
    if (isAdd) {
      setFiles((prevState) => {
        return [...prevState, data];
      });
    }
  };
  const top = (index: number) => {
    if (index == 0) {
      return;
    }
    let newList: any[];
    if (isSetBeforeHook) {
      newList = [...beforeHookList];
    } else {
      newList = [...afterHook];
    }

    const temp = newList[index - 1];
    newList[index - 1] = newList[index];
    newList[index] = temp;
    if (isSetBeforeHook) {
      setBeforeHookList(newList);
    } else {
      setAfterHook(newList);
    }
  };
  useEffect(() => {
    try {
      form.resetFields();
      // eslint-disable-next-line @typescript-eslint/no-use-before-define
      loadData();
    } catch (e) {}
  }, [props.defaultValue]);
  // eslint-disable-next-line react-hooks/exhaustive-deps
  const loadData = async () => {
    await getServerList();
    if (
      props.defaultValue &&
      props.defaultValue.after_upload_step_json &&
      props.defaultValue.after_upload_step_json.length > 0
    ) {
      setAfterHook(props.defaultValue.after_upload_step_json);
      setFiles(props.defaultValue.files ?? []);
    } else {
      setAfterHook([]);
      setFiles([]);
    }
    if (
      props.defaultValue &&
      props.defaultValue.before_upload_step_json &&
      props.defaultValue.before_upload_step_json.length > 0
    ) {
      setBeforeHookList(props.defaultValue.before_upload_step_json);
      setFiles(props.defaultValue.files ?? []);
    } else {
      setBeforeHookList([]);
      setFiles([]);
    }
    if (props.defaultValue.need_upload != undefined) {
      setIsPublish(true);
    }
  };

  const createBeforeHook = () => {
    setModelData({
      ext_params: '',
      create_time: '',
      delete_time: 0,
      docker_image: '',
      id: 0,
      process_id: 0,
      project_id: 0,
      run_step: 0,
      run_type: 0,
      step_name: '',
      step_template: '',
      template_args: '',
      template_id: 0,
      unique_id: '',
      update_time: '',
    });
    setIsSetBeforeHook(true);
    setShowModal(true);
  };
  const createAfterHook = () => {
    setModelData({
      ext_params: '',
      create_time: '',
      delete_time: 0,
      docker_image: '',
      id: 0,
      process_id: 0,
      project_id: 0,
      run_step: 0,
      run_type: 0,
      step_name: '',
      step_template: '',
      template_args: '',
      template_id: 0,
      unique_id: '',
      update_time: '',
    });
    setIsSetBeforeHook(false);
    setShowModal(true);
  };
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
  const showIsPublish = () => {
    if (isPublish) {
      return (
        <div>
          <Form.Item
            label="服务器配置"
            name="server_id_json"
            rules={[
              {
                required: true,
                message: '请选择需要部署的服务器!',
              },
            ]}
          >
            <Select
              mode="multiple"
              placeholder="请选择服务器"
              defaultValue={[]}
              onChange={() => {}}
              style={{ width: '100%' }}
            >
              {serverList.map((item: { server_name: string; id: number; ip: string }) => {
                // @ts-ignore
                return (
                  <Option key={item.id} value={item.id}>
                    {item.ip + ' ' + item.server_name}
                  </Option>
                );
              })}
            </Select>
          </Form.Item>
          <Form.Item
            label="输出路径"
            tooltip="相对于项目的相对路径,此路径下的文件将会被上传到配置好的服务器"
            name="output_dir"
            rules={[
              {
                required: false,
                message: '请输入部署路径!',
              },
            ]}
          >
            <Input />
          </Form.Item>
          <Form.Item
            hidden={true}
            label="主键ID"
            name="id"
            rules={[
              {
                required: false,
                message: '请输入部署路径!',
              },
            ]}
          >
            <Input />
          </Form.Item>
          <Form.Item
            label="上传路径"
            tooltip="绝对路径"
            name="upload_dir"
            rules={[
              {
                required: false,
                message: '请输入上传路径,上传到服务器的绝对路径!',
              },
            ]}
          >
            <Input />
          </Form.Item>
          <Form.Item
            label="上传忽略路径"
            tooltip="相对路径,此路径下的文件不同将不会被删除"
            name="upload_exclude_dir"
            rules={[
              {
                required: false,
                message: '请输入上传忽略路径!',
              },
            ]}
          >
            <TextArea rows={6} />
          </Form.Item>
          <Form.Item
            label="额外参数"
            tooltip="额外参数如--rsynctimeout=seconds 控制上传超时时间"
            name="ext_params"
            rules={[
              {
                required: false,
                message: '请输入上传忽略路径!',
              },
            ]}
          >
            <TextArea rows={6} />
          </Form.Item>
        </div>
      );
    }
    return;
  };
  // @ts-ignore
  // @ts-ignore
  // @ts-ignore
  // @ts-ignore
  // @ts-ignore
  // @ts-ignore
  return (
    <GridContent>
      <Files
        modelData={file}
        getForm={() => {}}
        open={showFiles}
        onCancel={() => {
          setShowFiles(false);
        }}
        onOk={(data: PRO.files) => {
          setShowFiles(false);
          addFiles(data);
        }}
      />
      {/*@ts-ignore*/}
      <Step
        getForm={(value: any) => {
          console.log(value);
        }}
        open={showModal}
        modelData={modelData}
        onCancel={() => {
          setShowModal(false);
        }}
        onOk={(data: any, formInstance: FormInstance) => {
          addHook(data);
          setShowModal(false);
          formInstance.resetFields();
        }}
      />
      <Form
        form={form}
        name="basic"
        labelCol={{
          span: 6,
        }}
        wrapperCol={{
          span: 16,
        }}
        initialValues={props.defaultValue}
        // onFinish={async (values) => {
        //   await handleSubmit(values as PRO.Project);
        // }}
        // onFinishFailed={onFinishFailed}
        autoComplete="off"
      >
        <Form.Item
          label="配置名称"
          name="name"
          rules={[
            {
              required: false,
              message: '请输入配置名称!',
            },
          ]}
        >
          <Input />
        </Form.Item>
        <Form.Item
          label="部署到服务器"
          name="need_upload"
          rules={[
            {
              required: true,
              message: '请选择是否发布到服务器!',
            },
          ]}
        >
          <Select
            onChange={(value) => {
              setIsPublish(value == '1');
            }}
          >
            <option value={1}>部署到服务器</option>
            <option value={2}>不部署</option>
          </Select>
        </Form.Item>
        {showIsPublish()}
        <Form.Item
          label="发布前置钩子"
          name="before_hook"
          tooltip="在跳板机上执行的命令"
          rules={[
            {
              required: false,
              message: '请输入GIT地址!',
            },
          ]}
        >
          <div>
            <Button onClick={createBeforeHook}>新建钩子</Button>
            <div className="hook_container">
              {beforeHookList.map((item, index) => {
                // eslint-disable-next-line react/jsx-key
                return (
                  <div className="hook_item" key={item.unique_id}>
                    <div>
                      <LeftOutlined
                        onClick={() => {
                          setIsSetBeforeHook(true);
                          top(index);
                        }}
                        style={{ marginLeft: '10px' }}
                      />
                      <EditOutlined
                        onClick={() => {
                          setIsSetBeforeHook(true);
                          editHook(item);
                        }}
                        style={{ marginLeft: '10px' }}
                      />
                    </div>
                    <div className="hook_name">钩子名:{item.step_name}</div>
                  </div>
                );
              })}
            </div>
          </div>
        </Form.Item>

        <Form.Item
          label="新增发布文件"
          name="files"
          tooltip="可以执行的文件,例如dockerfile,可以利用此文件进行docker 镜像构建，或者k8s部署"
          rules={[
            {
              required: false,
              message: '请输入GIT地址!',
            },
          ]}
        >
          <div>
            <Button
              onClick={() => {
                editFiles({ content: '', path: '', template_args: '', unique_id: '', id: '' });
              }}
            >
              新建文件
            </Button>
            <div className="hook_container">
              {files.map((item, index) => {
                // eslint-disable-next-line react/jsx-key
                return (
                  <div className="hook_item" key={item.unique_id}>
                    <div>
                      <LeftOutlined
                        onClick={() => {
                          setIsSetBeforeHook(true);
                          top(index);
                        }}
                        style={{ marginLeft: '10px' }}
                      />
                      <EditOutlined
                        onClick={() => {
                          setIsSetBeforeHook(true);
                          editFiles(item);
                        }}
                        style={{ marginLeft: '10px' }}
                      />
                    </div>
                    <div className="hook_name">文件名称:{item.path}</div>
                  </div>
                );
              })}
            </div>
          </div>
        </Form.Item>

        <Form.Item
          label="发布后置钩子"
          name="after_hook"
          tooltip="在部署的机器上执行的命令"
          rules={[
            {
              required: false,
              message: '请输入GIT地址!',
            },
          ]}
        >
          <div>
            <Button onClick={createAfterHook}>新建钩子</Button>
            <div className="hook_container">
              {afterHook.map((item, index) => {
                // eslint-disable-next-line react/jsx-key
                return (
                  <div className="hook_item" key={item.unique_id}>
                    <div>
                      <LeftOutlined
                        onClick={() => {
                          setIsSetBeforeHook(false);
                          top(index);
                        }}
                        style={{ marginLeft: '10px' }}
                      />
                      <EditOutlined
                        onClick={() => {
                          setIsSetBeforeHook(false);
                          editHook(item);
                        }}
                        style={{ marginLeft: '10px' }}
                      />
                    </div>
                    <div className="hook_name">钩子名:{item.step_name}</div>
                  </div>
                );
              })}
            </div>
          </div>
        </Form.Item>
      </Form>
    </GridContent>
  );
});

export default ProcessSetting;
